using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Comteck.Util;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using HorizontalAlignment = NPOI.SS.UserModel.HorizontalAlignment;

namespace Comteck.Winforms.Utils {
  public class WinFormFileExport {

    #region 导出无格式的Excel

    /// <summary>
    /// 导出无格式的Excell
    /// 
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="source"></param>
    /// <param name="collist"></param>
    /// <param name="filename"></param>
    /// <returns></returns>
    public static bool ExportNoFormatExcelByList<T>(IList<T> source, IList<string> collist, string filename) {
      // 导出的文件名
      string strSavePath = string.Empty;
      var dlgSave = new System.Windows.Forms.SaveFileDialog();
      dlgSave.Title = "导出Excel文件";// 对话框题目
      dlgSave.FileName = filename;
      dlgSave.Filter = "Microsoft Excel|*.xlsx";// 过滤格式
      if (dlgSave.ShowDialog() == System.Windows.Forms.DialogResult.OK) {
        strSavePath = dlgSave.FileName;
      }

      if (String.IsNullOrWhiteSpace(strSavePath)) {
        return false;
      }

      try {
        var stream = FileHelper_Excel.ExportList2Excel<T>(source,
             collist,
             "Sheet1",
             true, null, false,
             "xlsx");

        using (FileStream fs = new FileStream(strSavePath, FileMode.OpenOrCreate)) {
          stream.CopyTo(fs);
          stream.Close();
          fs.Close();
        }
      } catch {
        return false;
      }

      return true;
    }

    #endregion


    /// <summary>
    /// 大数据量多个sheet导出
    /// </summary>
    /// <typeparam name="T">数据源实体类</typeparam>
    /// <param name="objList">数据源</param>
    /// <param name="fileName">文件名称</param>
    /// <param name="btyBytes">导出数据流</param>
    /// <param name="columnInfo">显示列对应数据字典</param>
    /// <param name="listCount">每个sheet包含数据条数</param>
    /// <returns></returns>
    public static bool ExportExcelTest<T>(List<T> objList, string filename, ref byte[] btyBytes,
Dictionary<string, string> columnInfo = null, int listCount = 10000) {

      // 导出的文件名
      string strSavePath = string.Empty;
      var dlgSave = new System.Windows.Forms.SaveFileDialog();
      dlgSave.Title = "导出Excel文件";// 对话框题目
      dlgSave.FileName = filename;
      dlgSave.Filter = "Microsoft Excel|*.xlsx";// 过滤格式
      if (dlgSave.ShowDialog() == System.Windows.Forms.DialogResult.OK) {
        strSavePath = dlgSave.FileName;
      }

      if (String.IsNullOrWhiteSpace(strSavePath)) {
        return false;
      }

      try {

        bool bResult = false;
        //在内存中生成一个Excel文件：
        var book = new XSSFWorkbook();
        if (objList != null && objList.Count > 0) {
          double sheetCount = Math.Ceiling((double)objList.Count / listCount);
          for (int i = 0; i < sheetCount; i++) {
            ISheet sheet = null;
            sheet = book.CreateSheet("sheet" + i);
            sheet.DefaultRowHeight = 20 * 10;
            List<T> list = new List<T>();
            list = objList.Skip<T>(listCount * i).Take<T>(listCount).ToList();

            int rowIndex = 0;
            int StartColIndex = 0;
            int colIndex = StartColIndex;

            //创建表头样式
            ICellStyle style = book.CreateCellStyle();
            style.Alignment = HorizontalAlignment.Center;
            style.WrapText = true;
            IFont font = book.CreateFont();
            font.FontHeightInPoints = 16;
            //font.Boldweight = (short)FontBoldWeight.Bold;
            font.IsBold = true;
            font.FontName = "简体中文";
            style.SetFont(font);//HEAD 样式

            Type myType = null;
            myType = objList[0].GetType();
            //根据反射从传递进来的属性名信息得到要显示的属性
            List<PropertyInfo> myPro = new List<PropertyInfo>();
            PropertyInfo[] properties = myType.GetProperties();

            #region 定义表头
            int m = 0;
            if (columnInfo != null) {
              var rowheader = sheet.CreateRow(0);
              rowheader.Height = rowheader.Height = 20 * 20;
              foreach (string cName in columnInfo.Keys) {
                rowheader.CreateCell(m).SetCellValue(columnInfo[cName]);
                m++;
                PropertyInfo p = myType.GetProperty(cName);
                if (p != null) {
                  myPro.Add(p);

                }
              }
            }
            #endregion
            #region 定义表体并赋值
            //如果没有找到可用的属性则结束
            if (myPro.Count == 0) { return bResult; }
            foreach (T obj in list) {
              int n = 0;
              if (sheet != null) {
                rowIndex++;
                var sheetrow = sheet.CreateRow(rowIndex);
                sheetrow.Height = sheetrow.Height = 20 * 20;
                foreach (PropertyInfo p in myPro) {
                  dynamic val = p.GetValue(obj, null) ?? "";
                  string valtype = val.GetType().ToString();
                  if (valtype.ToLower().IndexOf("decimal", StringComparison.Ordinal) > -1) {
                    val = Convert.ToDouble(val);
                  } else if (valtype.ToLower().IndexOf("datetime", StringComparison.Ordinal) > -1) {
                    val = val.ToString("yyyy-MM-dd HH:mm:ss");
                    if (val.Equals("0001-01-01 00:00:00")) {
                      val = "";
                    }
                  }
                  sheetrow.CreateCell(n).SetCellValue(val);
                  n++;
                }
              }

            }
            #endregion
          }
        } else {
          //在工作薄中建立工作表
          XSSFSheet sheet = book.CreateSheet() as XSSFSheet;
          sheet.SetColumnWidth(0, 30 * 256);
          if (sheet != null) sheet.CreateRow(0).CreateCell(0).SetCellValue("暂无数据！");
        }
        using (FileStream fs = new FileStream(strSavePath, FileMode.OpenOrCreate)) {
          book.Write(fs);
          fs.Close();
        }
      } catch {
        return false;
      }

      return true;

    }


    public static bool GridToExcels(List<DataTable> dts, string filename, int indexType) {

      // 导出的文件名
      string strSavePath = string.Empty;
      var dlgSave = new System.Windows.Forms.SaveFileDialog();
      dlgSave.Title = "导出Excel文件";// 对话框题目
      dlgSave.FileName = filename;
      dlgSave.Filter = "Microsoft Excel|*.xlsx";// 过滤格式
      if (dlgSave.ShowDialog() == System.Windows.Forms.DialogResult.OK) {
        strSavePath = dlgSave.FileName;
      }

      if (String.IsNullOrWhiteSpace(strSavePath)) {
        return false;
      }


      bool BSave = false;
      try {
        var workbook = new XSSFWorkbook();
        foreach (DataTable dt in dts) {
          ISheet sheet = workbook.CreateSheet(dt.TableName);
          ICellStyle HeadercellStyle = workbook.CreateCellStyle();
          HeadercellStyle.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;
          HeadercellStyle.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;
          HeadercellStyle.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;
          HeadercellStyle.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;
          HeadercellStyle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;
          //cellstyle.Alignment = HorizontalAlignment.Center;
          //字体
          NPOI.SS.UserModel.IFont headerfont = workbook.CreateFont();
          //headerfont.Boldweight = (short)FontBoldWeight.Bold;
          headerfont.IsBold = true;
          HeadercellStyle.SetFont(headerfont);

          IRow row = sheet.CreateRow(0);
          ICell cell = row.CreateCell(0);
          cell.SetCellValue("采购员:" + dt.TableName);
          ICellStyle style = workbook.CreateCellStyle();
          sheet.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(0, 0, 0, 3));
          //用column name 作为列名
          int icolIndex = 0;
          IRow headerRow = sheet.CreateRow(1);
          foreach (DataColumn item in dt.Columns) {
            cell = headerRow.CreateCell(icolIndex);
            cell.SetCellValue(item.ColumnName);
            cell.CellStyle = HeadercellStyle;
            icolIndex++;
          }
          ICellStyle cellStyle = workbook.CreateCellStyle();
          //为避免日期格式被Excel自动替换，所以设定 format 为 『@』 表示一率当成text来看
          //cellStyle.DataFormat = XSSFDataFormat;
          cellStyle.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;
          cellStyle.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;
          cellStyle.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;
          cellStyle.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;
          NPOI.SS.UserModel.IFont cellfont = workbook.CreateFont();
          //cellfont.Boldweight = (short)FontBoldWeight.Normal;
          cellfont.IsBold = true;
          cellStyle.SetFont(cellfont);
          if (indexType == 1) {
            //建立内容行
            int iRowIndex = 2;
            int iCellIndex = 0;
            foreach (DataRow Rowitem in dt.Rows) {
              IRow DataRow = sheet.CreateRow(iRowIndex);
              foreach (DataColumn Colitem in dt.Columns) {
                cell = DataRow.CreateCell(iCellIndex);
                string valtype = Rowitem[Colitem].GetType().ToString();
                if (valtype.ToLower().IndexOf("decimal", StringComparison.Ordinal) > -1) {
                  cell.SetCellValue(Convert.ToDouble(Rowitem[Colitem]));
                } else {
                  cell.SetCellValue(Rowitem[Colitem].ToString());
                }
                cell.CellStyle = cellStyle;

                iCellIndex++;
              }
              iCellIndex = 0;
              iRowIndex++;
            }
            //自适应列宽
            for (int i = 0; i < icolIndex; i++) {
              sheet.AutoSizeColumn(i);
            }
          }

        }
        using (FileStream fs = new FileStream(strSavePath, FileMode.Create)) {
          workbook.Write(fs);
          fs.Close();
        }
        //FileStream file = new FileStream(filename, FileMode.OpenOrCreate);
        //workbook.Write(file);
        //file.Flush();
        //file.Close();
        BSave = true;
      } catch (Exception ex) {
        throw new Exception(ex.Message);
      }
      return BSave;
    }


  }
}
